﻿using System.Collections.ObjectModel;
using System.Linq;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using GBlason.Common.CustomCommand;
using GBlason.ViewModel;
using GBlason.ViewModel.General;

namespace GBlason.Control.Aggregate
{
    /// <summary>
    /// Interaction logic for ActionHistory.xaml
    /// </summary>
    public partial class ActionHistory
    {
        public ActionHistory()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Commands the undo can execute.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Windows.Input.CanExecuteRoutedEventArgs"/> instance containing the event data.</param>
        private void CommandUndoCanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if (GlobalApplicationViewModel.GetApplicationViewModel.CurrentlyDisplayedFile != null)
                e.CanExecute =
                    GlobalApplicationViewModel.GetApplicationViewModel.CurrentlyDisplayedFile.CommandsApplied.
                        HasUndoableCommand;
            else
                e.CanExecute = false;
        }

        /// <summary>
        /// Commands the undo executed.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Windows.Input.ExecutedRoutedEventArgs"/> instance containing the event data.</param>
        private void CommandUndoExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            var command = CommandHistoryDataGrid.SelectedItem == null
                              ? GlobalApplicationViewModel.GetApplicationViewModel.CurrentlyDisplayedFile.CommandsApplied.LastUndoableCommand
                              : CommandHistoryDataGrid.SelectedItem as CommandGeneric;
            if (command == null) return;
            if (!command.Done)
                command =
                    GlobalApplicationViewModel.GetApplicationViewModel.CurrentlyDisplayedFile.CommandsApplied.
                        LastUndoableCommand;
            //for all the command from the last to the selected (command) we undo
            GlobalApplicationViewModel.GetApplicationViewModel.CurrentlyDisplayedFile.CommandsApplied.UndoCommandsUntil(command);
            ItemsChanged(CommandHistoryDataGrid.ItemsSource, null);
        }

        /// <summary>
        /// Check if the redo is possible
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Windows.Input.CanExecuteRoutedEventArgs"/> instance containing the event data.</param>
        private void CommandRedoCanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = GlobalApplicationViewModel.GetApplicationViewModel.CurrentlyDisplayedFile != null && GlobalApplicationViewModel.GetApplicationViewModel.CurrentlyDisplayedFile.CommandsApplied.HasRedoableCommand;
        }

        /// <summary>
        /// Execute the redo on the command
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.Windows.Input.ExecutedRoutedEventArgs"/> instance containing the event data.</param>
        private void CommandRedoExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            var command = CommandHistoryDataGrid.SelectedItem == null
                             ? GlobalApplicationViewModel.GetApplicationViewModel.CurrentlyDisplayedFile.CommandsApplied.FirstRedoableCommand
                             : CommandHistoryDataGrid.SelectedItem as CommandGeneric;
            if (command == null) return;
            if (command.Done)
                command =
                    GlobalApplicationViewModel.GetApplicationViewModel.CurrentlyDisplayedFile.CommandsApplied.
                        FirstRedoableCommand;
            //for all the command from the last to the selected (command) we undo
            GlobalApplicationViewModel.GetApplicationViewModel.CurrentlyDisplayedFile.CommandsApplied.RedoCommandsUntil(command);
            ItemsChanged(CommandHistoryDataGrid.ItemsSource, null);
        }


        private void CommandHistoryDataGridTargetUpdated(object sender, DataTransferEventArgs e)
        {
            var datagrid = e.Source as DataGrid;

            if (datagrid != null)
            {
                var dataSource = datagrid.ItemsSource as ObservableCollection<CommandGeneric>;
                if (dataSource != null)
                    dataSource.CollectionChanged += ItemsChanged;
            }

        }

        void ItemsChanged(object sender, System.EventArgs e)
        {
            var dataSource = sender as ObservableCollection<CommandGeneric>;

            if (dataSource == null || dataSource.Count <= 0) return;
            var lastDone = dataSource.LastOrDefault(ds => ds.Done);
            if (lastDone == default(CommandGeneric))
                lastDone = dataSource.FirstOrDefault();
            if (lastDone != default(CommandGeneric) && CommandHistoryDataGrid != null)
                CommandHistoryDataGrid.ScrollIntoView(lastDone);
        }
    }
}
